package aaa

import java.io.IOException
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Path
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.security.SecureRandom


object Utils {
    /*
      🦜 : substitute the content in the file between

      ....
      %%% --------------------------------------------------
      <content to be substituted>
      %%% --------------------------------------------------
    */
    fun isSubstituteLine(line: String): Boolean {
        var l = line.trim { it <= ' ' }
        return l.startsWith("%%%")
    }

    @Throws(IOException::class, RuntimeException::class)
    fun <T : Dt.ITeXWorkable> substituteSpecialLines(l: List<T>, dummy: T) {
        val subs: MutableList<String> = ArrayList()
        for (i in l) {
            subs.add(i.toTeXLine())
        }

        if (subs.isEmpty()) {
            subs.add(dummy.getTeXEmpty())
        }

        substituteSpecialLines(dummy.getTeXTemplate(), subs)
    }

    @Throws(IOException::class, RuntimeException::class)
    fun substituteSpecialLines(n: String?, subs: List<String>?) {
        val templateFile = FileSystems.getDefault().getPath("tex", n)
        val outFile = FileSystems.getDefault().getPath(".generated-tex", n)
        substituteSpecialLines(templateFile, outFile, subs)
    }

    @Throws(IOException::class, RuntimeException::class)
    fun substituteSpecialLines(
        templateFile: Path?,
        outFile: Path?,
        subs: List<String>?
    ) {
        // 1. read all lines
        val readLines = Files.readAllLines(templateFile)

        // 2. get the `before` and `after`
        val i: MutableList<Int> = ArrayList() // indexes of substitute lines
        for (k in readLines.indices) {
            val line = readLines[k]
            if (isSubstituteLine(line)) {
                i.add(k)
            }
        }
        if (i.size < 2) {
            throw RuntimeException("there should be at least two substitute lines in the template file")
        }
        // 🦜 : spit the lines into two parts (one before the first index line and one after the last index line)
        val l1: List<String> = readLines.subList(0, i[0] + 1) // +1 to include the last line (the substitute line)
        val l2: List<String> =
            readLines.subList(i[i.size - 1], readLines.size) // -1 to include the first line (the substitute line)

        // 3. concat and write
        val lines: MutableList<String> = ArrayList()
        lines.addAll(l1)
        lines.addAll(subs!!)
        lines.addAll(l2)


        Files.write(outFile, lines)
    }

    // 生成随机 SHA-256 哈希值的方法
    @JvmStatic
    @Throws(NoSuchAlgorithmException::class)
    fun generateRandomSha256Hash(): String {
        val randomBytes = generateRandomBytes()

        // 创建 MessageDigest 实例，选择 SHA-256 算法
        val digest = MessageDigest.getInstance("SHA-256")

        // 更新摘要
        digest.update(randomBytes)

        // 获取摘要的字节数组
        val hashedBytes = digest.digest()

        // 将字节数组转换为十六进制字符串
        val stringBuilder = StringBuilder()
        for (hashedByte in hashedBytes) {
            stringBuilder.append(((hashedByte.toInt() and 0xff) + 0x100).toString(16).substring(1))
        }

        // 返回生成的 SHA-256 哈希值
        return stringBuilder.toString()
    }

    // 生成指定长度的随机字节数组
    private fun generateRandomBytes(): ByteArray {
        val secureRandom = SecureRandom()
        val randomBytes = ByteArray(16) // 16 bytes for SHA-256
        secureRandom.nextBytes(randomBytes)
        return randomBytes
    }
}
